#include "xservice_proxy.h"
#include <protobuf/xmsg_com.pb.h>
#include <XCom.h>
#include <XMsg.h>
#include "xservice_proxy_client.h"
#include <XTools.h>
#include <thread>
#include"register/register_client/xregister_client.h"
XServiceProxy::XServiceProxy()
{
}

XServiceProxy::~XServiceProxy()
{
}

bool XServiceProxy::Init()
{
    // 1 重注册中心获取微服务列表
#if 0
    xmsg::XServiceMap serviceMap;
    auto smap = serviceMap.mutable_service_map();
    xmsg::XServiceMap::XServiceList list;
    {
        auto service = list.add_services();
        service->set_ip("127.0.0.1");
        service->set_port(20011);
        service->set_name("dir");
    }
    // {
    //     auto service = list.add_services();
    //     service->set_ip("127.0.0.1");
    //     service->set_port(20012);
    //     service->set_name("dir");
    // }
    smap->operator[]("dir") = list;
    // serviceMap.mutable_service_map()->insert({"xdir", "127.0.0.1:8080"});
#endif
    // 2 与微服务建立连接,便利XServiceMap
    // for (auto &m : *smap)
    // {
    //     client_map_[m.first] = std::vector<XServiceProxyClient *>();
    //     client_map_last_index_[m.first] = 0;
    //     for (auto &s : m.second.services())
    //     {
    //         auto proxy = new XServiceProxyClient();
    //         proxy->setServerIP(s.ip().c_str());
    //         proxy->setServerPort(s.port());
    //         proxy->StartConnect();
    //         client_map_[m.first].push_back(proxy);
    //     }
    // }
    return true;
}

bool XServiceProxy::SendMsg(xmsg::XMsgHead *head, XMsg *message, XMsgEvent *ev)
{
    if (!head || !message)
        return false;
    auto service_name = head->service_name();
    client_map_mutex_.lock();
    auto &&list = client_map_.find(service_name);
    if (list == client_map_.end())
    {
        client_map_mutex_.unlock();
        XCOM_LOG_DEBUG(service_name<<" service not found");
        return false;
    }
    client_map_mutex_.unlock();
    std::unique_lock<std::mutex> lock(callbacks_mutex_);
    int cur_index = client_map_last_index_[service_name];
    int list_size = list->second.size();
    for (int i = 0; i < list_size; i++)
    {
        cur_index++;
        cur_index %= list_size;
        client_map_last_index_[service_name] = cur_index;
        auto client = list->second[cur_index];
        if (client->isConnected())
        {
            callbacks_[ev] = client;
            return client->SendMsg(head, message, ev);
        }
    }
    XCOM_LOG_DEBUG("can't connect to service");
    return false;
}

void XServiceProxy::DelEvent(XMsgEvent *ev)
{
    std::unique_lock<std::mutex> lock(callbacks_mutex_);
    if (callbacks_.find(ev) == callbacks_.end())
    {
        return;
    }
    auto client = callbacks_.find(ev)->second;
    client->DelEvent(ev);
    // callbacks_.erase(ev);
}

void XServiceProxy::Start()
{
    std::thread th(&XServiceProxy::Main, this);
    th.detach();
}

void XServiceProxy::Stop()
{
    is_exit_ = true;
}

void XServiceProxy::Main()
{
    // 自动重连
    while (!is_exit_)
    {
        // 从注册中心获取微服务列表更新
        // 定时获取微服务列表
        XRegisterClient::Get()->GetServiceReq(nullptr);
        xmsg::XServiceMap *service_map = XRegisterClient::Get()->GetAllService();
        if(!service_map){
            XCOM_LOG_DEBUG("service_map is null!");
            std::this_thread::sleep_for(std::chrono::seconds(60));
            continue;
        }
        auto smap = service_map->service_map();
        // 便利微服务名称
        for (auto &m : smap)
        {
            // 遍历同一个服务的微服务列表
            for(auto& s:m.second.services()){
                const std::string &server_name = s.name();
                if(server_name==API_GATEWAY_NAME){
                    continue;
                }
                std::unique_lock<std::mutex> lock(client_map_mutex_);
                // 此服务是否已经连接
                if(client_map_.find(m.first)==client_map_.end()){
                    client_map_[m.first] = std::vector<XServiceProxyClient *>();
                    client_map_last_index_[m.first] = 0;
                }
                bool isfind = false;
                // 查找
                for(auto& c:client_map_[m.first]){
                    if(c->serverIP()==s.ip()&&(uint32_t)c->servePort()==s.port()){
                        isfind = true;
                        break;
                    }
                }
                if(isfind)
                    continue;
                auto proxy = new XServiceProxyClient();
                proxy->setServerIP(s.ip().c_str());
                proxy->setServerPort(s.port());
                // 设置对象在关闭时不会自动删除，以确保资源的显式管理
                proxy->setDeleteOnClose(false);
                proxy->StartConnect();
                client_map_[m.first].push_back(proxy);
                client_map_last_index_[m.first] = 0;
            }
        }
        for(auto& c:client_map_){
            for(auto& cc:c.second){
                if(cc->isConnected()) continue;
                if(!cc->isConnecting()){
                    cc->connect();
                }
            }
        }
        std::this_thread::sleep_for(std::chrono::seconds(60));
    }
}
